home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / dvips / dopage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-01-28  |  9.4 KB  |  293 lines

  1. /*
  2.  *   Main page drawing procedure.  Interprets the page commands.  A simple
  3.  *   (if lengthy) case statement interpreter.  
  4.  */
  5. #include "structures.h" /* The copyright notice in that file is included too! */
  6.  
  7. /*
  8.  *   The external routines we use:
  9.  */
  10. extern void error() ;
  11. extern void pageinit() ;
  12. extern void drawrule() ;
  13. extern shalfword dvibyte() ;
  14. extern halfword twobytes() ;
  15. extern integer threebytes() ;
  16. extern integer signedquad() ;
  17. extern shalfword signedbyte() ;
  18. extern shalfword signedpair() ;
  19. extern integer signedtrio() ;
  20. extern void dospecial() ;
  21. extern void drawchar() ;
  22. #ifndef XENIX
  23. extern double floor() ;
  24. #endif
  25. extern void fontdef() ;
  26. extern void pageend() ;
  27. /*
  28.  *   Now the external variables.
  29.  */
  30. extern fontdesctype *curfnt ;
  31. extern fontmaptype *ffont ;
  32. extern quarterword *curpos, *curlim ;
  33. extern integer hh, vv ;
  34. extern real conv ;
  35. extern FILE *bitfile ;
  36. extern int actualdpi ;
  37. extern frametype frames[] ;
  38. extern int maxdrift ;
  39. #ifdef XENIX
  40. #define PixRound(x) ((integer)(x + (iconv >> 1)) / iconv)
  41. #else
  42. #define PixRound(x) (floor(((x) * conv) + 0.5))
  43. #endif
  44. /*
  45.  *   Now we have the dopage procedure.
  46.  *   Most error checking is suppressed because the prescan has already
  47.  *   verified that the DVI data is OK....except for stack over/underflow.
  48.  */
  49. static struct dvistack {
  50.   integer hh, vv ;
  51.   integer h, v, w, x, y, z ;
  52. } stack[STACKSIZE] ;
  53. void
  54. dopage()
  55. {
  56.    register shalfword cmd ;
  57.    register integer p ;
  58.    register chardesctype *cd ;
  59.    register integer h ;
  60.    register fontmaptype *cfnt ;
  61.    register frametype *frp = frames ;
  62.    integer fnt ;
  63.    struct dvistack *sp = stack ;
  64.    integer v, w, x, y, z ;
  65.    integer roundpos ;
  66.    integer thinspace ;
  67.    integer vertsmallspace ;
  68. #ifdef XENIX
  69.    integer iconv ;
  70.  
  71.    iconv = (integer)(1.0 / conv + 0.5) ;
  72. #endif
  73.    pageinit() ;
  74.    thinspace = vertsmallspace = (integer)(0.025*DPI/conv) ; /* 0.025 inches */
  75.    hh = vv = h = v = w = x = y = z = 0 ;
  76.    curfnt = NULL ;
  77. beginloop:
  78.    switch (cmd=dvibyte()) {
  79. case 138: goto beginloop ; /* nop command does nuttin */
  80. case 128: cmd = dvibyte() ; /* set1 command drops through to setchar */
  81. default: /* these are commands 0 (setchar0) thru 127 (setchar127) */
  82.    cd = &(curfnt->chardesc[cmd]) ;
  83.    if (cd->flags & EXISTS) {
  84.       if (curfnt->loaded == 2) { /* virtual character being typeset */
  85.          sp->hh = hh + cd->pixelwidth ; sp->vv = vv ;
  86.          sp->h = h + cd->TFMwidth ; sp-> v = v ;
  87.          sp->w = w ; sp->x = x ; sp->y = y ; sp->z = z ;
  88.          if (++sp >= &stack[STACKSIZE]) error("! Out of stack space") ;
  89.          w = x = y = z = 0 ; /* will be in relative units at new stack level */
  90.          frp->curp = curpos ;
  91.          frp->curl = curlim ;
  92.          frp->ff = ffont ;
  93.          frp->curf = curfnt ;
  94.          if (++frp == &frames[MAXFRAME] )
  95.             error("! virtual recursion stack overflow") ;
  96.          cd = curfnt->chardesc + cmd ;
  97.          curpos = cd->packptr + 2 ;
  98.          curlim = curpos + (256*(long)(*cd->packptr)+(*(cd->packptr+1))) ;
  99.          ffont = curfnt->localfonts ;
  100.          if (ffont) {
  101.             curfnt = ffont->desc ;
  102.             thinspace = curfnt->thinspace ;
  103.          } else {
  104.             curfnt = NULL ;
  105.             thinspace = vertsmallspace ;
  106.          }
  107.          goto beginloop ;
  108.       }
  109.       drawchar(cd, cmd) ;
  110.    }
  111.    h += cd->TFMwidth ;
  112.    hh += cd->pixelwidth ;
  113.    goto setmotion ;
  114. case 129: case 130: case 131: case 133: case 134: case 135: case 136:
  115. case 139: case 236: case 237: case 238: case 244: case 245: case 246:
  116. case 247: case 248: case 249: case 250: case 251: case 252: case 253:
  117. case 254: case 255: /* unimplemented or illegal commands */
  118.    error("! synch") ;
  119. case 132: case 137: /* rules */
  120.  { integer ry, rx , rxx, ryy ;
  121.    ry = signedquad() ; rx = signedquad() ;
  122.    if (rx>0 && ry>0) {
  123.       if (curpos) {
  124.          rx = scalewidth(rx, (frp-1)->curf->scaledsize) ;
  125.          ry = scalewidth(ry, (frp-1)->curf->scaledsize) ;
  126.       }
  127.       rxx = (conv * rx + 0.9999999) ;
  128.       ryy = (conv * ry + 0.9999999) ;
  129.       drawrule(rxx, ryy) ;
  130.    }
  131.    if (cmd == 137) goto beginloop ;
  132.    h += rx ; hh += rxx ;
  133.    goto setmotion ;
  134.  }
  135. case 141: /* push */
  136.    sp->hh = hh ; sp->vv = vv ; sp->h = h ; sp->v = v ;
  137.    sp->w = w ; sp->x = x ; sp->y = y ; sp->z = z ;
  138.    if (++sp >= &stack[STACKSIZE]) error("! Out of stack space") ;
  139.    goto beginloop ;
  140. case 140: /* eop or end of virtual character */
  141.    if (curpos == NULL) break ; /* eop */
  142.    --frp ;
  143.    curfnt = frp->curf ;
  144.    thinspace = (curfnt) ? curfnt->thinspace : vertsmallspace ;
  145.    ffont = frp->ff ;
  146.    curlim = frp->curl ;
  147.    curpos = frp->curp ;
  148.    /* falls through */
  149. case 142: /* pop */
  150.    if (--sp < stack) error("! More pops than pushes") ;
  151.    hh = sp->hh ; vv = sp->vv ; h = sp->h ; v = sp->v ;
  152.    w = sp->w ; x = sp->x ; y = sp->y ; z = sp->z ;
  153.    goto beginloop ;
  154. case 143: /* right1 */
  155.    p = signedbyte() ; goto horizontalmotion ;
  156. case 144: /* right2 */
  157.    p = signedpair() ; goto horizontalmotion ;
  158. case 145: /* right3 */
  159.    p = signedtrio() ; goto horizontalmotion ;
  160. case 146: /* right4 */
  161.    p = signedquad() ; goto horizontalmotion ;
  162. case 147: /* w0 */
  163.    p = w ; goto horizontalmotion ;
  164. case 148: /* w1 */
  165.    p = w = signedbyte() ; goto horizontalmotion ;
  166. case 149: /* w2 */
  167.    p = w = signedpair() ; goto horizontalmotion ;
  168. case 150: /* w3 */
  169.    p = w = signedtrio() ; goto horizontalmotion ;
  170. case 151: /* w4 */
  171.    p = w = signedquad() ; goto horizontalmotion ;
  172. case 152: /* x0 */
  173.    p = x ; goto horizontalmotion ;
  174. case 153: /* x1 */
  175.    p = x = signedbyte() ; goto horizontalmotion ;
  176. case 154: /* x2 */
  177.    p = x = signedpair() ; goto horizontalmotion ;
  178. case 155: /* x3 */
  179.    p = x = signedtrio() ; goto horizontalmotion ;
  180. case 156: /* x4 */
  181.    p = x = signedquad() ; goto horizontalmotion ;
  182. case 157: /* down1 */
  183.    p = signedbyte() ; goto verticalmotion ;
  184. case 158: /* down2 */
  185.    p = signedpair() ; goto verticalmotion ;
  186. case 159: /* down3 */
  187.    p = signedtrio() ; goto verticalmotion ;
  188. case 160: /* down4 */
  189.    p = signedquad() ; goto verticalmotion ;
  190. case 161: /* y0 */
  191.    p = y ; goto verticalmotion ;
  192. case 162: /* y1 */
  193.    p = y = signedbyte() ; goto verticalmotion ;
  194. case 163: /* y2 */
  195.    p = y = signedpair() ; goto verticalmotion ;
  196. case 164: /* y3 */
  197.    p = y = signedtrio() ; goto verticalmotion ;
  198. case 165: /* y4 */
  199.    p = y = signedquad() ; goto verticalmotion ;
  200. case 166: /* z0 */
  201.    p = z ; goto verticalmotion ;
  202. case 167: /* z1 */
  203.    p = z = signedbyte() ; goto verticalmotion ;
  204. case 168: /* z2 */
  205.    p = z = signedpair() ; goto verticalmotion ;
  206. case 169: /* z3 */
  207.    p = z = signedtrio() ; goto verticalmotion ;
  208. case 170: /* z4 */
  209.    p = z = signedquad() ; goto verticalmotion ;
  210. case 171: case 172: case 173: case 174: case 175: case 176: case 177:
  211. case 178: case 179: case 180: case 181: case 182: case 183: case 184:
  212. case 185: case 186: case 187: case 188: case 189: case 190: case 191:
  213. case 192: case 193: case 194: case 195: case 196: case 197: case 198:
  214. case 199: case 200: case 201: case 202: case 203: case 204: case 205:
  215. case 206: case 207: case 208: case 209: case 210: case 211: case 212:
  216. case 213: case 214: case 215: case 216: case 217: case 218: case 219:
  217. case 220: case 221: case 222: case 223: case 224: case 225: case 226:
  218. case 227: case 228: case 229: case 230: case 231: case 232: case 233:
  219. case 234: case 235: /* font selection commands */
  220.    if (cmd < 235) fnt = cmd - 171 ; /* fntnum0 thru fntnum63 */
  221.    else fnt = dvibyte() ; /* fnt1 */
  222.    for (cfnt=ffont; cfnt; cfnt = cfnt->next)
  223.       if (cfnt->fontnum == fnt) break ;
  224.    curfnt = cfnt->desc ;
  225.    thinspace = curfnt->thinspace ;
  226.    goto beginloop ;
  227. case 243: /*fntdef1 */
  228.    skipover(13) ;
  229.    skipover(dvibyte() + dvibyte()) ;
  230.    goto beginloop ;
  231. case 239: /* xxx1 */
  232.    p = dvibyte() ;
  233.    dospecial(p) ;
  234.    goto beginloop ;
  235. case 240: /* xxx2 */
  236.    p = twobytes() ;
  237.    dospecial(p) ;
  238.    goto beginloop ;
  239. case 241: /* xxx3 */
  240.    p = threebytes() ;
  241.    dospecial(p) ;
  242.    goto beginloop ;
  243. case 242: /* xxx4 */
  244.    p = signedquad() ;
  245.    dospecial(p) ;
  246.    goto beginloop ;
  247.  
  248. /*
  249.  *   The calculations here are crucial to the appearance of the document.
  250.  *   If the motion is small, we round the amount of relative motion; otherwise,
  251.  *   we update the position and round the new position.  Then we check to
  252.  *   insure that the rounded position didn't accumulate an error that was
  253.  *   greater than maxdrift.
  254.  */
  255. verticalmotion:
  256. /* vertical motion cases */
  257.       if (curpos)
  258.          p = scalewidth(p, (frp-1)->curf->scaledsize) ;
  259.       v += p ;
  260.       if (p >= vertsmallspace) vv = PixRound(v) ;
  261.       else if (p <= -vertsmallspace) vv = PixRound(v) ;
  262.       else 
  263.       { vv += PixRound(p) ;
  264.         roundpos = PixRound(v) ;
  265.         if (roundpos - vv > maxdrift) vv = roundpos - maxdrift ;
  266.         else if (vv - roundpos > maxdrift) vv = roundpos + maxdrift ;
  267.       }
  268.       goto beginloop ;
  269. /*
  270.  *   Horizontal motion is analogous. We know the exact width of each
  271.  *   character in pixels. Kerning is distinguished from space between
  272.  *   words if it's less than a thinspace and not more negative than would
  273.  *   occur when an accent is being positioned by backspacing.
  274.  */
  275. horizontalmotion:
  276. /* horizontal motion cases */
  277.       if (curpos)
  278.          p = scalewidth(p, (frp-1)->curf->scaledsize) ;
  279.       h += p ;
  280.       if (p >= thinspace || p <= -6 * thinspace) {
  281.          hh = PixRound(h) ; goto beginloop ;
  282.       }
  283.       else hh += PixRound(p) ;
  284. setmotion:
  285.       roundpos = PixRound(h) ;
  286.       if (roundpos - hh > maxdrift) { hh = roundpos - maxdrift ; }
  287.       else if (hh - roundpos > maxdrift) { hh = roundpos + maxdrift ; }
  288. goto beginloop ;
  289.  
  290.    } /* end of the big switch */
  291.    pageend() ;
  292. }
  293.